package com.ay.weixin.fdc.admin.category.domain;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.lizar.ioc.Container;
import org.lizar.ioc.module.Module;
import org.lizar.util.StringHelper;

import com.ay.weixin.fdc.admin.category.db.IbatisCategoryDao;

public class CategoryLoader extends Module {

	private IbatisCategoryDao cat_dao;
	
	private static Map<Integer,Category> category_map=new HashMap<Integer,Category>();
	
	private static Map<String,Map<Integer,Category>> sorted_map=new HashMap<String,Map<Integer,Category>>();
	
	private ReadWriteLock rwl = new ReentrantReadWriteLock();
	
	@Override
	public void init_property() throws Exception {
		// TODO Auto-generated method stub
		cat_dao=Container.get(IbatisCategoryDao.class);
	}

	@Override
	public void init_component() throws Exception {
		// TODO Auto-generated method stub
		reload_category();
	}
	
	public Map<Integer,Category> get(String groups){
		
		Map<Integer,Category> map= sorted_map.get(groups);
		if(map==null){
			map=new LinkedHashMap<Integer,Category>();
		}
		return map;
	}
	
	/**
	 *@param 
	 * groups
	 * parent_id
	 * name
	 * 
	 * @return category
	 * 
	 * */
	public Category retrieve(String groups,int parent_id,String name){
		Map<Integer,Category> map= sorted_map.get(groups);
		if(map==null){
			return null;
		}
		for(Category c:map.values()){
			if(c.getParent_id()==parent_id&&StringHelper.equals(c.getName(),name)){
				return c;
			}
		}
		return null;
	}
	
	public Category get(int id){
		rwl.readLock().lock();
		Category category=null;
		try{
			category=category_map.get(id);
		}finally{
			rwl.readLock().unlock();
		}
		return category;
	}
	
	
	public void reload_category(){
		
		rwl.writeLock().lock();
		List<Category> clist=null;
		try{
			clist=cat_dao.getAll();
			category_map.clear();
			clear_sort_map();
			build_map(clist);
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			rwl.writeLock().unlock();
		}
	}
	
	private void clear_sort_map(){
		Iterator<Entry<String,Map<Integer,Category>>> itr=sorted_map.entrySet().iterator();
		Entry<String,Map<Integer,Category>> ent=null;
		Entry<Integer,Category> enty=null;
		for(;itr.hasNext();){
			ent=itr.next();
			Iterator<Entry<Integer,Category>> gitr=ent.getValue().entrySet().iterator();
			for(;gitr.hasNext();){
				enty=gitr.next();
				enty.getValue().clearSubs();
			}
			ent.getValue().clear();
		}
		sorted_map.clear();
	}
	
	private void build_map(List<Category> clist){
		if(clist==null||clist.isEmpty())return;
		Iterator<Category> itr=clist.iterator();
		Category category=null;
		Map<Integer,Category> map=null;
		for(;itr.hasNext();){
			category=itr.next();
			category_map.put(category.getId(), category);
			if(category.getParent_id()==-1){
				map=sorted_map.get(category.getGroups());
				if(map==null){
					map=new LinkedHashMap<Integer,Category>();
					sorted_map.put(category.getGroups(),map);
				}
				map.put(category.getId(), category);
				itr.remove();
			}
		}
		
		Iterator<Entry<String,Map<Integer,Category>>> itr_mp=sorted_map.entrySet().iterator();
		Entry<String,Map<Integer,Category>> ent=null;
		Entry<Integer,Category> enty=null;
		for(;itr_mp.hasNext();){
			ent=itr_mp.next();
			Iterator<Entry<Integer,Category>> gitr=ent.getValue().entrySet().iterator();
			for(;gitr.hasNext();){
				enty=gitr.next();
				build_sub_map(enty.getValue(),clist);
			}
		}
		
	}
	
	private void build_sub_map(Category c,List<Category> clist){
		Category category=null;
		Iterator<Category> itr=clist.iterator();
		for(;itr.hasNext();){
			category=itr.next();
			if(c.getId()==category.getParent_id()){
				c.setSubCategory(category);
				build_sub_map(category,clist);
				itr.remove();
			}
		}
		
		
		
	}
	
}
